<template>
  <div class="chat-container">
    <!-- 对话记录区域 -->
    <div class="chat-history" ref="chatHistory">
      <div v-for="(message, index) in messages" :key="index" :class="['message', message.role]">
        <div class="message-content">
          
          <p>{{ message.content }}</p>
        </div>
      </div>
      <div v-if="isLoading" class="loading">AI 正在思考...</div>
    </div>

    <!-- 用户输入区域 -->
    <div class="input_all">
      <div class="input_area"> 
        <textarea
          v-model="question"
          placeholder="请输入你的问题"
          @keyup.enter="submitQuestion"
          :disabled="isLoading"
          @input="adjustTextareaHeight"
          ref="textarea"
        ></textarea>
      </div>
      <div style="width: calc( 100% - 40px );display: flex;justify-content: space-between;;padding: 0 20px;">
        <div
          class="input_btn"
          :class="{ active: isNetworkActive }"
          @click="toggleNetwork"
        >
          联网搜索
        </div>
        <button class="btngo" @click="submitQuestion" :disabled="isLoading">
          <img src="../../public/send.png" alt="" srcset="" style="width: 20px;height: 20px;">
        </button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, nextTick, onMounted, onUnmounted } from 'vue';

// 用户输入的问题
const question = ref('');

// 对话记录
const messages = ref([]);

// 加载状态
const isLoading = ref(false);
const isNetworkActive = ref(false);

// 获取 DOM 引用
const chatHistory = ref(null);
const textarea = ref(null);

// WebSocket 连接
const socket = ref(null);

// 动态调整 textarea 高度
const adjustTextareaHeight = () => {
  const textareaEl = textarea.value;
  textareaEl.style.height = 'auto'; // 重置高度
  textareaEl.style.height = `${Math.min(textareaEl.scrollHeight, 800)}px`; // 设置高度
};

// 提交问题
const submitQuestion = () => {
  if (!question.value.trim()) {
    return;
  }

  // 检查 WebSocket 连接状态
  if (socket.value && socket.value.readyState !== WebSocket.OPEN) {
    if (socket.value.readyState === WebSocket.CONNECTING) {
      // 如果连接正在建立中，等待连接打开后再发送消息
      socket.value.addEventListener('open', () => {
        sendQuestion();
      }, { once: true });
    } else {
      // 如果连接已关闭或发生错误，重新创建连接
      socket.value = new WebSocket('ws://124.223.75.64:8081/v1/chat-messages-ws'); // 替换为实际的 WebSocket URL
      socket.value.addEventListener('open', () => {
        sendQuestion();
      }, { once: true });
      socket.value.addEventListener('message', handleMessage);
      socket.value.addEventListener('close', handleClose);
      socket.value.addEventListener('error', handleError);
    }
  } else {
    // 如果连接已打开，直接发送消息
    sendQuestion();
  }
};

const sendQuestion = () => {
  // 将用户的问题添加到对话记录
  messages.value.push({ role: 'user', content: question.value });
  const textareaEl = textarea.value;
  textareaEl.style.height = '100px'; 
  // 清空输入框
  const userQuestion = question.value;
  question.value = '';

  // 设置加载状态
  isLoading.value = true;

  // 创建要发送的 JSON 对象
  const messageToSend = {
    "user": "abc-123",
    "query": userQuestion,
    "conversation_id": "",
    "lx": isNetworkActive.value ? '联网搜索解答' : '离线解答'
  };

  // 发送问题到 WebSocket
  console.log(messageToSend);
  socket.value.send(JSON.stringify(messageToSend));

  // 等待 DOM 更新后滚动到最新消息
  nextTick(() => {
    scrollToLatestMessage();
  });
};

const toggleNetwork = () => {
  isNetworkActive.value = !isNetworkActive.value;
};

// 滚动到最新消息
const scrollToLatestMessage = () => {
  const chatHistoryEl = chatHistory.value;
  if (chatHistoryEl) {
    const lastMessage = chatHistoryEl.lastElementChild;
    if (lastMessage) {
      lastMessage.scrollIntoView({ behavior: 'smooth' }); // 平滑滚动
    }
  }
};

// WebSocket 事件处理
const handleOpen = () => {
  console.log('WebSocket 连接已打开');
};

let accumulatedData = '';

const handleMessage = (event) => {
  // 假设服务器返回的数据是分块的 JSON 对象，每行一个 JSON
  const chunks = event.data.split('\n'); // 按换行符分割数据块

  chunks.forEach(chunk => {
    if (chunk.trim() === '') return; // 忽略空行

    try {
      const response = JSON.parse(chunk); // 解析 JSON
      // 检查是否是 AI 的回答
      if (response.answer) {
        // 更新最后一条消息或添加新消息
        const lastMessage = messages.value[messages.value.length - 1];
        if (lastMessage && lastMessage.role === 'assistant') {
          // 如果是流式数据，追加内容
          lastMessage.content += response.answer;
        } else {
          // 如果是新消息，添加到对话记录
          messages.value.push({ role: 'assistant', content: response.answer });
        }

        // 滚动到最新消息
        nextTick(() => {
          scrollToLatestMessage();
        });
      }
    } catch (error) {
      console.error('解析 JSON 失败:', chunk, error);
    }
  });

  // 取消加载状态
  isLoading.value = false;
};

const handleClose = (event) => {
  console.log('WebSocket 连接已关闭', event);
  if (event.code === 1000) {
    console.log('连接正常关闭');
  } else {
    console.log('连接异常关闭，代码:', event.code, '原因:', event.reason);
  }
};

const handleError = (error) => {
  console.error('WebSocket 错误:', error);
  messages.value.push({ role: 'assistant', content: '抱歉，获取回答失败，请稍后重试。' });

  // 等待 DOM 更新后滚动到最新消息
  nextTick(() => {
    scrollToLatestMessage();
  });

  // 取消加载状态
  isLoading.value = false;
};

// 初始化 WebSocket 连接
onMounted(() => {
  socket.value = new WebSocket('ws://124.223.75.64:8081/v1/chat-messages-ws'); // 替换为实际的 WebSocket URL

  socket.value.addEventListener('open', handleOpen);
  socket.value.addEventListener('message', handleMessage);
  socket.value.addEventListener('close', handleClose);
  socket.value.addEventListener('error', handleError);
});

// 清理 WebSocket 连接
onUnmounted(() => {
  if (socket.value) {
    socket.value.close();
  }
});
</script>

<style>
/* 全局样式 */
body {
  margin: 0;
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
  background-color: #f5f5f5;
}

/* 聊天容器 */
.chat-container {
  height: 80%;
  margin: 20px auto;
  padding: 20px;
  background-color: white;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* 对话记录区域 */
.chat-history {
  height: 500px;
  overflow-y: auto;
  padding: 10px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  background-color: #fafafa;
  margin-bottom: 20px;
}
textarea {
  border-radius: 10px;
  background-color: #f3f4f6;
  width: 100%;
  min-height: 100px; /* 最小高度 */
  max-height: 300px; /* 最大高度 */
  padding: 10px;
  color: #333 !important;
  font-size: 16px;
  border: 1px solid #f3f4f6;
  border-radius: 8px;
  outline: none;
  resize: none; /* 禁止用户手动调整大小 */
  overflow-y: auto; /* 内容超出时显示滚动条 */
  transition: border-color 0.3s;
}

/* 消息样式 */
.message {
  margin-bottom: 15px;
  display: flex;
}

.message-content {

  max-width: 70%;
  padding: 10px 15px;
  border-radius: 12px;
  position: relative;
}

/* 用户消息 */
.user .message-content {
  background-color: #007bff;
  color: white;
  margin-left: auto;
}

/* AI 消息 */
.assistant .message-content {

  color: #333;
}

/* 加载状态 */
.loading {
  text-align: center;
  color: #666;
  font-style: italic;
  padding: 10px;
}

/* 输入区域 */
.input_all {
  border-radius: 10px;
  min-height: 200px;
  display: flex;
  flex-direction: column;
  align-items: start;
  gap: 10px;
  background-color: #f3f4f6;
}
.input_area {
  border-radius: 10px;
  background-color: #f3f4f6;
  width: 90%;
  display: flex;
  gap: 10px;
}
.btngo {
  width: 40px;
  height: 40px;
  border-radius: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.input_btn {
  width: 100px;
  height: 40px;
  border-radius: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  background-color: #fff;
  color: #333;
}
input {
  flex: 1;
  padding: 10px;
  font-size: 16px;
  border: 1px solid #e0e0e0;
  border-radius: 8px;
  outline: none;
  transition: border-color 0.3s;
}

input:focus {
  border-color: #007bff;
}

button {
  padding: 10px 20px;
  font-size: 16px;
  background-color: #007bff;
  color: white;
  border: none;
  border-radius: 8px;
  cursor: pointer;
  transition: background-color 0.3s;
}

button:hover {
  background-color: #0056b3;
}

button:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

.input_btn.active {
  background-color: #C3DAF8;
  color: #4D6BFE;
}
</style>